<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8"/>
    <meta content="width=device-width, initial-scale=0.9" name="viewport">
    <meta content="DoubleAm的博客,贺雄彪的博客,贺雄彪,鲸落oh,江湖小栈" name="description">
    <meta Content="DoubleAm的博客,贺雄彪的博客,贺雄彪,鲸落oh,江湖小栈" name="keywords">
    <meta content="DoubleAm" name="author">
    <link href="/images/favicon.png" rel="shortcut icon">
    <title>飞机大战</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        font-family: "Microsoft yahei", serif;
      }
      li {
        list-style-type: none;
      }
      body {
        overflow: hidden;
        user-select: none;
        -moz-user-select: -moz-none;
        -ms-user-select: none;
      }
      #box {
        position: relative;
        width: 512px;
        height: 768px;
        margin: 0 auto;
      }
      #map {
        overflow: hidden;
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background: url("img/bg_1.jpg");
      }
      #level {
        position: absolute;
        top: 0;
        left: 0;
        z-index: 1;
        width: 100%;
        height: 100%;
      }
      #level h1 {
        font-size: 40px;
        padding-top: 60px;
        padding-bottom: 150px;
        line-height: 60px;
        text-align: center;
        color: #fff;
      }
      #level p {
        margin: 30px auto;
        width: 200px;
        height: 35px;
        line-height: 35px;
        text-align: center;
        background: #fff;
        font-weight: bolder;
        cursor: pointer;
      }
      #level p:hover {
        background: pink;
        color: #fff;
      }
      #map .plane, #map .biu, #map .enemy, #map .boom, #map .boom2 {
        position: absolute;
      }
      #map .plane {
        z-index: 8;
      }
      #map .biu {
        z-index: 10;
      }
      #map .boom2 {
        z-index: 11;
        animation: bling 2s 1;
        animation-fill-mode: forwards;
      }
      #map .enemy {
        z-index: 9;
      }
      #map .boom {
        z-index: 7;
        animation: fade .8s 1;
        animation-fill-mode: forwards;
      }
      @keyframes fade {
        from {
          opacity: 1;
        }
        to {
          opacity: 0;
        }
      }
      @keyframes bling {
        0% {
          opacity: 1;
        }
        20% {
          opacity: 0;
        }
        40% {
          opacity: 1;
        }
        60% {
          opacity: 0;
        }
        80% {
          opacity: 1;
        }
        100% {
          opacity: 0;
        }
      }
      #score {
        display: none;
        position: absolute;
        top: 10px;
        left: 10px;
        color: #fff;
        line-height: 20px;
        font-size: 14px;
        font-weight: bold;
        z-index: 20;
      }
      #restart {
        display: none;
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        z-index: 30;
      }
      #restart p {
        width: 300px;
        height: 40px;
        line-height: 20px;
        margin: 140px auto;
        color: #fff;
      }
      #restart p span {
        display: block;
        font-weight : bolder;
        font-size: 22px;
        text-align: center;
      }
      #restart .p1 span {
        color: red;
      }
      #restart .p2 span {
        color: #ffa80c;
      }
      #restart .p3 {
        font-family: "楷体";
        font-size: 20px;
        width: 100px;
        height: 35px;
        background: rgb(255,255,255);
        background: rgba(255,255,255,.8);
        color: #000;
        font-weight: bolder;
        line-height: 35px;
        text-align: center;
        border-radius: 3px;
        cursor: pointer;
      }
      #restart .p3:hover {
        background: white;
      }
      #level p{
        border-radius: 5px;
      }
      #level a{
        color: black;
        text-decoration: none;
      }
    </style>
  </head>
  <body>
    <div id="box">
      <div id="level">
        <h1>飞机大战</h1>
        <p>简单</p>
        <p>中等</p>
        <p>困难</p>
        <p style="color: #f00">开挂</p>
        <a href='/'><p>更多</p></a>
      </div>
      <div id="map">
        <div id="BiuAll"></div>
      </div>
      <div id="score">0</div>
      <div id="restart">
        <p class="p1"><span>0</span></p>
        <p class="p2"><span>Biugle</span></p>
        <p class="p3">重新开始</p>
      </div>
    </div>
    <script>
      window.requestAnimationFrame = window.requestAnimationFrame || function (fn) {
        return setTimeout(fn, 1000 / 60)
      };
      window.cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout;

      //全局变量
      var oBox = document.getElementById("box"),
              oScore = document.getElementById("score"),
              oRe = document.getElementById("restart"),
              oLevel = document.getElementById("level"),
              oMap = document.getElementById("map"),
              oBiuAll = document.getElementById("BiuAll"),
              allBiu = oBiuAll.children,
              allReChild = oRe.children,
              boxOffsetTop = oBox.offsetTop,
              boxOffsetLeft = oBox.offsetLeft;

      //启动
      exe();

      //初始选择难度界面的点击事件
      function exe() {

        //难度选择
        var aP = oLevel.getElementsByTagName("p");
        for (var i = 0, length = aP.length; i < length; i++) {
          (function (i) {
            aP[i].onclick = function (e) {
              e = e || window.event;
              startGame(i, {
                x: e.clientX - boxOffsetLeft,
                y: e.clientY - boxOffsetTop
              });//第一个实参为序号 ，第二个实参为存储着鼠标距离map边缘距离的json
            };
          })(i);
        }

        //restart按钮
        allReChild[2].onclick = function (ev) {
          cancelAnimationFrame(oMap.bgTimer);//停止背景滚动
          oRe.style.display = "none";
          oLevel.style.display = "block";
          oScore.innerHTML = 0;
          oMap.innerHTML = "<div id='BiuAll'></div>";
          oBiuAll = document.getElementById("BiuAll");
          allBiu = oBiuAll.children;
        };
      }

      //开始游戏
      function startGame(level, pos) {

        clearMap(); //执行 隐藏和清理

        MapBg(level); //执行 Map背景相关操作
        var p = plane(level, pos); //执行 创建我军
        enemy(level, p); //执行 创建敌军
        //enemy(level , plane(level , pos));
        oBox.score = 0;//得分清零
      }

      //隐藏和清理
      function clearMap() {
        oScore.style.display = "block";
        oLevel.style.display = "none";//隐藏关卡选择框
      }

      //Map背景选择与运动
      function MapBg(level) {
        oMap.style.backgroundImage = "url('img/bg_" + (level + 1) + ".jpg')";

        (function m() {
          oMap.bgPosY = oMap.bgPosY || 0;
          oMap.bgPosY++;
          oMap.style.backgroundPositionY = oMap.bgPosY + 'px';
          oMap.bgTimer = requestAnimationFrame(m);
        })();
      }

      //创建我军
      function plane(level, pos) {
        //创建我军图片
        var oImg = new Image();//document.createElement("img");
        oImg.src = "img/plane_0.png";
        oImg.width = 70;
        oImg.height = 70;
        oImg.className = "plane";
        oImg.style.left = pos.x - oImg.width / 2 + 'px';
        oImg.style.top = pos.y - oImg.height / 2 + 'px';
        oMap.appendChild(oImg);

        //边界值
        var leftMin = -oImg.width / 2,
                leftMax = oMap.clientWidth - oImg.width / 2,
                topMin = 0,
                topMax = oMap.clientHeight - oImg.height / 2;

        //加入mousemove事件
        document.onmousemove = function (ev) {
          ev = ev || window.event;
          //获取飞机实时坐标，并限制边界值
          var left = ev.clientX - boxOffsetLeft - oImg.width / 2;
          var top = ev.clientY - boxOffsetTop - oImg.height / 2;
          left = Math.max(leftMin, left);
          left = Math.min(leftMax, left);
          top = Math.max(topMin, top);
          top = Math.min(topMax, top);
          //赋值
          oImg.style.left = left + 'px';
          oImg.style.top = top + 'px';
        };

        //调用子弹函数
        fire(oImg, level);

        return oImg;
      }

      //我军子弹
      function fire(oImg, level) {
        oBox.biuInterval = setInterval(function () {
          if (oBox.score >= 500) {
            createBiu(true, -1);
            createBiu(true, 1);
          } else {
            createBiu();
          }
        }, [100, 200, 200, 15][level]);

        function createBiu(index, d) {
          //创建子弹
          var oBiu = new Image();
          oBiu.src = "img/fire.png";
          oBiu.width = 30;
          oBiu.height = 30;
          oBiu.className = "biu";

          var left = oImg.offsetLeft + oImg.width / 2 - oBiu.width / 2;
          var top = oImg.offsetTop - oBiu.height + 5;

          if (index) {
            left += oBiu.width * d;
          }

          oBiu.style.left = left + "px";
          oBiu.style.top = top + 'px';


          oBiuAll.appendChild(oBiu);

          //子弹运动
          function m() {
            if (oBiu.parentNode) {
              var top = oBiu.offsetTop - 20;
              if (top < -oBiu.height) {
                oBiuAll.removeChild(oBiu);
              } else {
                oBiu.style.top = top + 'px';
                requestAnimationFrame(m);
              }
            }
          }
          //将运动执行队列放后面，不然子弹会直接初始就在 top-50 的位置
          setTimeout(function () {
            requestAnimationFrame(m);
          }, 50);
        }
      }

      //创建敌军
      function enemy(level, oPlane) {
        var w = oMap.clientWidth,
                h = oMap.clientHeight;

        var speed = [5, 6, 8, 8][level]; //敌军下落速度

        var num = 1;
        oBox.enemyIntetval = setInterval(function () {
          var index = num % 30 ? 1 : 0;

          //生成敌军
          var oEnemy = new Image();
          oEnemy.index = index;
          oEnemy.HP = [20, 1][index];
          oEnemy.speed = speed + (Math.random() * 0.6 - 0.3) * speed;
          oEnemy.speed *= index ? 1 : 0.5;
          oEnemy.src = "img/enemy_" + ["big", "small"][index] + ".png";
          oEnemy.className = "enemy";
          oEnemy.width = [104, 54][index];
          oEnemy.height = [80, 40][index];
          oEnemy.style.left = Math.random() * w - oEnemy.width / 2 + 'px';
          oEnemy.style.top = -oEnemy.height + 'px';
          oMap.appendChild(oEnemy);
          num++;

          //敌军运动
          function m() {
            if (oEnemy.parentNode) {
              var top = oEnemy.offsetTop;
              top += oEnemy.speed;
              if (top >= h) {
                oBox.score--; //漏掉飞机减分
                oScore.innerHTML = oBox.score;
                oMap.removeChild(oEnemy);
              } else {
                oEnemy.style.top = top + 'px';
                //子弹碰撞检测
                for (var i = allBiu.length - 1; i >= 0; i--) {
                  var objBiu = allBiu[i];
                  if (coll(oEnemy, objBiu)) {
                    oBiuAll.removeChild(objBiu);//移除子弹
                    oEnemy.HP--;
                    if (!oEnemy.HP) {
                      oBox.score += oEnemy.index ? 2 : 20; //打掉飞机加分
                      oScore.innerHTML = oBox.score;
                      boom(oEnemy.offsetLeft, oEnemy.offsetTop, oEnemy.width, oEnemy.height, index ? 0 : 2);//敌军爆炸图
                      oMap.removeChild(oEnemy);//移除敌军
                      return;
                    }
                  }
                }
                //我军碰撞检测
                if (oPlane.parentNode && coll(oEnemy, oPlane)) {
                  boom(oEnemy.offsetLeft, oEnemy.offsetTop, oEnemy.width, oEnemy.height, index ? 0 : 2);//敌军爆炸图
                  boom(oPlane.offsetLeft, oPlane.offsetTop, oPlane.width, oPlane.height, 1);//我军爆炸图
                  oMap.removeChild(oEnemy);//移除敌军
                  oMap.removeChild(oPlane);//移除我军
                  GameOver();
                  return;
                }
                requestAnimationFrame(m);
              }
            }
          }
          requestAnimationFrame(m);
        }, [350, 150, 120, 40][level]);
      }

      //爆炸函数
      function boom(l, t, w, h, i) {
        var oBoom = new Image();
        oBoom.src = "img/" + ["boom_small", "plane_0", "boom_big"][i] + ".png";
        oBoom.className = 'boom' + ["", "2", ""][i];
        oBoom.width = w;
        oBoom.height = h;
        oBoom.style.left = l + "px";
        oBoom.style.top = t + 'px';
        oMap.appendChild(oBoom);
        setTimeout(function () {
          oBoom.parentNode && oMap.removeChild(oBoom);
        }, [1200, 2500, 1200][i]);
      }

      //两个物体 碰撞检测
      function coll(obj1, obj2) {
        var T1 = obj1.offsetTop,
                B1 = T1 + obj1.clientHeight,
                L1 = obj1.offsetLeft,
                R1 = L1 + obj1.clientWidth;

        var T2 = obj2.offsetTop,
                B2 = T2 + obj2.clientHeight,
                L2 = obj2.offsetLeft,
                R2 = L2 + obj2.clientWidth;

        return !(B1 < T2 || R1 < L2 || T1 > B2 || L1 > R2);
      }

      //游戏结束
      function GameOver() {
        document.onmousemove = null; //清除移动事件
        clearInterval(oBox.biuInterval);//不再产生新子弹
        clearInterval(oBox.enemyIntetval);//不再产生新敌军
        restart();
      }

      //结算+重新开始
      function restart() {
        oScore.style.display = "none";

        var s = oBox.score;
        var honor;

        if (s < -300) {
          honor = "闪避+MAX！！！";
        } else if (s < 10) {
          honor = "菜得…算了我不想说了…";
        } else if (s < 30) {
          honor = "抠脚侠！";
        } else if (s < 100) {
          honor = "初级飞机大师";
        } else if (s < 200) {
          honor = "渐入佳境";
        } else if (s < 500) {
          honor = "中级飞机大师";
        } else if (s < 1000) {
          honor = "高级飞机大师";
        } else if (s < 5000) {
          honor = "终极飞机大师";
        } else {
          honor = "孤独求败！";
        }

        oRe.style.display = "block";
        allReChild[0].children[0].innerHTML = s;
        allReChild[1].children[0].innerHTML = honor;
      }
    </script>
  </body>
</html>